package com.iot08.admin.controller.base;


import com.iot08.admin.service.AgentService;
import com.iot08.admin.service.ChannelService;
import com.iot08.admin.service.DeviceModelsService;
import com.iot08.admin.utils.PageData;
import com.iot08.common.constant.Const;
import com.iot08.common.entity.admin.Channel;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.admin.service.UserService;
import com.iot08.common.entity.app.DeviceModels;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

@Slf4j
public class BaseController {

    @Resource
    private UserService userService;
    @Resource(name = "securityManager")
    private DefaultWebSecurityManager securityManager;

    @Resource
    private DeviceModelsService deviceModelsService;

    @Resource
    private ChannelService channelService;

    @Resource
    private AgentService agentService;

    //全局变量缓存, 厂商 <Channel>
    public static List<Channel> channelList = new ArrayList<>();

//    public static ConcurrentHashMap<String, > channelMap = new ConcurrentHashMap<String, Channel>();

    //全局变量缓存, 设备型号 <DeviceModels>
    public static List<DeviceModels> deviceModelsList = new ArrayList<>();


    public List<DeviceModels> getDevModels(){
        if(deviceModelsList.isEmpty()){
            Query query  = new Query(Criteria.where("delete").ne(1));
            log.info("初始化设备型号缓存");
            List<DeviceModels> deviceModels = deviceModelsService.find(query);
            deviceModelsList = deviceModels;
        }
        return deviceModelsList;
    }

    public List<Channel> getChannels(){
        if(channelList.isEmpty()){
            log.info("初始化厂商缓存");
            List<Channel> channels = channelService.findAll();
            channels.addAll(agentService.doChangeChannelList());
            channelList = channels;
        }
        return channelList;
    }

    /**
     * 得到PageData
     */
    protected PageData getPageData() {
        return new PageData(this.getRequest());
    }

    /**
     * 得到request对象
     */
    protected HttpServletRequest getRequest() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request;
    }

    /**
     * 获取当前请求ip地址
     *
     * @time: 2020/9/10 9:38
     * @author: Rock
     * @version 1.0
     */
    protected String getRemortIP() {
        HttpServletRequest request = getRequest();
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isEmpty(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 获取session中的登录信息
     *
     * @return
     * @author:rock
     * @time:2020年8月11日 下午3:51:57
     */
    protected SysUser getSessionUser() {
        //shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser != null) {
            Session session = currentUser.getSession();
            if (session != null) {
                return (SysUser) session.getAttribute(Const.SESSION_USER);
            }
        }
        return null;
    }

    /**
     * 重置当前登录账户信息
     *
     * @time: 2020/9/10 9:19
     * @author: Rock
     * @version 1.0
     */
    protected void resetSessionUser() {
        //shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser != null) {
            Session session = currentUser.getSession();
            if (session != null) {
                SysUser user = (SysUser) session.getAttribute(Const.SESSION_USER);
                if (user != null) {
                    user = userService.findById(user.getId());
                    session.setAttribute(Const.SESSION_USER, user);
                }
            }
        }
    }

    /**
     * @time: 2020/9/10 11:15
     * @author: Rock
     * @version 1.0
     */
    protected void delSessionUser() {
        //shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();

        session.removeAttribute(Const.SESSION_USER);
        //shiro销毁登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }

    /**
     * 清楚指定用户session
     *
     * @time: 2020/9/10 15:09
     * @author: Rock
     * @version 1.0
     */
    protected void delSessionUserById(String id) {
        // 获取shiro的sessionManager
        DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();
        // 获取所有已登录用户的session列表
        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
        if (sessions != null) {
            for (Session onlineSession : sessions) {
                SysUser u = (SysUser) onlineSession.getAttribute(Const.SESSION_USER);
                if (u != null && u.getId().equals(id)) {
                    sessionManager.getSessionDAO().delete(onlineSession);
                }
            }
        }
    }

    /**
     * 获取当前用户拥有的按钮权限
     *
     * @time: 2020/8/21 18:03
     * @author: Rock
     * @version 1.0
     */
    protected Set<String> getMyBut(String menuId) {
        //shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        if (StringUtils.isNotEmpty(menuId) && currentUser != null) {
            Session session = currentUser.getSession();
            if (session != null) {
                Map<String, Set<String>> map = (Map<String, Set<String>>) session.getAttribute(Const.SESSION_USER_BUT);
                if (map != null) {
                    return map.get(menuId);
                }
            }
        }
        return null;
    }

    /**
     * @param [inputStream]
     * @time: 2020/8/31 15:58
     * @author: Rock
     * @version 1.0
     */
    protected byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

}
